//
//  BLU.m
//  KangarooDoctor
//
//  Created by 廖罡 on 2024/2/1.
//

#import "BLU.h"



@interface BLU ()
<CBCentralManagerDelegate,
CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *manager;
@property (nonatomic, strong) CBCharacteristic *character;
@property (nonatomic, strong) NSString * pageName;
@property (nonatomic, strong) NSString * uuid;
@end

@implementation BLU

+(instancetype) shared
{
    static BLU *s = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        s = [BLU new];
    });
    return s;
}

-(void)startWithPageName: (NSString *) name uuid:(nonnull NSString *)uuid
{
    self.pageName = name;
    self.uuid = uuid;
    self.manager = [[CBCentralManager alloc] initWithDelegate:self queue:dispatch_get_main_queue()];
}

-(void)stop
{
    if (self.peripheral != nil) {
        [self.manager cancelPeripheralConnection:self.peripheral];
        self.peripheral = nil;
    }
    
    [self.manager stopScan];
    self.manager = nil;
}



- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{

    NSLog(@"%@",central);
    switch (central.state) {
        case CBManagerStatePoweredOn:
        {
            [self.delegate bluStatusDidChange:@"蓝牙可用，已打开, 正在扫描周围的可用设备"];
            NSLog(@"打开，可用");
            NSArray *arr = @[];
            NSDictionary *options = @{};
            [self.manager scanForPeripheralsWithServices:arr options:options];
            //            [_manager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@(NO)}];
        }
            break;
        case CBManagerStateUnsupported:
            [self.delegate bluStatusDidChange:@"不支持蓝牙"];
            break;
        case CBManagerStatePoweredOff:
            [self.delegate bluStatusDidChange:@"蓝牙可用, 未打开"];
            NSLog(@"可用，未打开");
            break;
        case CBManagerStateUnauthorized:
            [self.delegate bluStatusDidChange:@"未授权, 请在设置/权限中, 允许亚都使用蓝牙"];
            NSLog(@"程序未授权");
            break;
        case CBManagerStateResetting:
            NSLog(@"CBCentralManagerStateResetting");
            break;
        case CBManagerStateUnknown:
            NSLog(@"CBCentralManagerStateUnknown");
            break;
    }
}


- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI
{
    if (peripheral.name.length <= 0) {
        return ;
    }
    
//    if ([peripheral.name isEqualToString:@"Bluetooth BP"]) {
        NSMutableArray<CBPeripheral *> * list = [[NSMutableArray alloc] init];
        [list addObject:peripheral];
    
        NSLog(@"peripheral: %@", peripheral);
        NSLog(@"1111111 %@", self.delegate );
        [self.delegate getDeviceList:list];
//    }
    
    NSLog(@"发现设备: %@   %@   %@", peripheral, advertisementData, RSSI );
//    NSLog(@"发现设备: %@, identifier: %@, advertisementData: %@, RSSI: %@", peripheral.name, peripheral.identifier,advertisementData,RSSI);
    
//    if ([peripheral.name isEqualToString:@"Bluetooth BP"]) {
//        self.peripheral = peripheral;
//        
//        [self.delegate bluStatusDidChange:@"已发现,血压计，开始连接"];
//        NSLog(@"连接设备: %@", peripheral.name);
//        [self.manager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
//        [peripheral setDelegate:self];
//        [self.manager stopScan];
//    }
 
}

- (void)connectPeripheral:(CBPeripheral *)peripheral {
    [self.manager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey:@(YES)}];
}


- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"didConnectPeripheral, 连接成功后，查找服务");
    [self.delegate bluStatusDidChange:@"已经连接蓝牙，请开始需要的服务"];
    
    [peripheral setDelegate:self];
    [peripheral discoverServices:nil];
    [self.manager stopScan];
}

- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error
{
    [self.delegate bluStatusDidChange:[NSString stringWithFormat:@"连接血压计失败, %@", error]];
//    [self.delegate bluStatusDidChange:@"连接血压计失败"];
    NSLog(@"didFailToConnectPeripheral");
}

-(void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    self.peripheral = nil;
    self.character = nil;
    [self.delegate bluDidDisconnect];
}

#pragma mark - CBPeripheralDelegate

- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(nullable NSError *)error
{
    NSString *UUID = [peripheral.identifier UUIDString];
    
    //指定 uuid ，则需要匹配对应的uuid
//    if( self.uuid != NULL && ![UUID isEqualToString:self.uuid] ){
//        //主动断开蓝牙
//        return;
//    }
    NSLog(@"发现了%@ 的服务:%@", peripheral.name, UUID);
    [self.delegate bluStatusDidChange:@"发现了血压计的服务, 正在等待数据"];
    
    if (error) {
        NSLog(@"出错");
        return;
    }
    

    for (CBService *service in peripheral.services) {
        NSLog(@"service11:%@",service.UUID.UUIDString);
//        if( [service.UUID.UUIDString isEqualToString:@"FFF0"] ){
            //如果我们知道要查询的特性的CBUUID，可以在参数一中传入CBUUID数组。
            [peripheral discoverCharacteristics:nil forService:service];
//        }
    }
}



//再然后是遍历服务中的特性：
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(nullable NSError *)error
{
    
    NSLog(@"did Discover Characteristics ForService");
    if (error) {
        NSLog(@"出错");
        return;
    }
    
    for (CBCharacteristic * character in service.characteristics) {
        
        NSLog(@"character: %@", character);
        
        // 这是一个枚举类型的属性
        CBCharacteristicProperties properties = character.properties;
        if (properties & CBCharacteristicPropertyBroadcast) {
            NSLog(@"如果是广播特性");
        }
        
        if (properties & CBCharacteristicPropertyRead) {
            NSLog(@"如果具备读特性，即可以读取特性的value");
            [peripheral readValueForCharacteristic:character];
        }

        
        if (properties & CBCharacteristicPropertyWriteWithoutResponse) {
            
            
            NSLog(@"蓝牙·111111111111");
            NSLog(@"如果具备写入值不需要响应的特性");
            self.character = character;
            //这里保存这个可以写的特性，便于后面往这个特性中写数据
//            if( [self.pageName isEqualToString:@"BLUDeviceListController"] ){
//                
////                Byte byte[] = {0xFD,0xFD,0xFA,0x04,0x16,0x01,0x02,0x03,0x04,0x05,0x0D,0x0A};
////                NSData * data = [[NSData alloc] initWithBytes:byte length:12];BLUDeviceListController
////                [peripheral writeValue:data forCharacteristic: character type:CBCharacteristicWriteWithoutResponse];
//            }
//            else {
                
            NSLog(@"蓝牙·2222222222");
                Byte byte[] = {0xFD,0xFD,0xFA,0x05,0x0D,0x0A};
                NSData * data = [[NSData alloc] initWithBytes:byte length:6];
                [peripheral writeValue:data forCharacteristic: character type:CBCharacteristicWriteWithoutResponse];
//                [self.delegate startMessare];
//            }
        }
        
        if (properties & CBCharacteristicPropertyWrite) {
//            self.character = character;
//            NSLog(@"如果具备写入值的特性，这个应该会有一些响应");
            
            NSLog(@"蓝牙·3333333");
            
            NSString * text = @"hello world";
            
            NSDictionary *dataDict = @{@"username": @"MiMi_5G", @"password": @"MM1681688"};
            NSError *error = nil;
            NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dataDict options:0 error:&error];
            [peripheral writeValue:jsonData forCharacteristic: character type: CBCharacteristicWriteWithResponse];
        }
        
        if (properties & CBCharacteristicPropertyNotify) {
            NSLog(@"如果具备通知的特性，无响应");
            [peripheral setNotifyValue:YES forCharacteristic:character];
        }
        
    }
}

- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if (error) {
        // 写入失败
        NSLog(@"写入失败 %@", error);
        
    } else {
        // 写入成功
        NSLog(@"写入成功", characteristic);
    }
}





//然后通知的代理方法如下：
- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
    if (error) {
        NSLog(@"错误didUpdateNotification：%@",error);
        return;
    }
    
    CBCharacteristicProperties properties = characteristic.properties;
    if (properties & CBCharacteristicPropertyRead) {
        NSLog(@"如果具备读特性，即可以读取特性的value");
        [peripheral readValueForCharacteristic:characteristic];
    }
}



// 读取新值的结果
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    if (error) {
        NSLog(@"错误：%@",error);
        return;
    }
    
    NSData *data = characteristic.value;
    if (data.length <= 0) {
        return;
    }

    NSString * content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
//    CBPeripheralStateConnected
    NSLog(@"收到新的数据: %@", content);
    NSLog(@"peripheral.state: %ld", peripheral.state);
    
    /***
         将获取的数据上传到 ui 叶秘啊
     */
    [self.delegate didReadData:data.bytes len: data.length];
    
}

- ( void ) writeStartData {
    
    
//    if( self.character ){
//        
//        NSLog(@"开始尝试写数据。。。。。");
//        Byte byte[] = {0xFD,0xFD,0xFA,0x04,0x16,0x01,0x02,0x03,0x04,0x05,0x0D,0x0A};
//        NSData * data = [[NSData alloc] initWithBytes:byte length:12];
//        
//        NSLog(@"%@", data);
//        [self.peripheral writeValue:data forCharacteristic: self.character type:CBCharacteristicWriteWithoutResponse];
//      
//    }
  
}


//到这里，获取蓝牙外设广播发送出来的值就已经完毕了。
//想要向蓝牙外设写入数据，则调用如下方法：
-(void)write{
    
    //[peripheral writeValue:infoData forCharacteristic:_chatacter type:CBCharacteristicWriteWithoutResponse];
    
    //另外取消与某蓝牙外设的连接方法是：
//    [self.manager cancelPeripheralConnection:peripheral];
}
@end


//https://juejin.cn/post/6844903887237988360
